# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load("@com_github_johnynek_bazel_jar_jar//:jar_jar.bzl", "jar_jar")
load("@google_bazel_common//testing:test_defs.bzl", "gen_java_tests")

# Produce an unshaded export jar based on :compiler_lib
load("@rules_jvm_external//:defs.bzl", "java_export")
load("//:bazel/expand_template_with_defines.bzl", "expand_template_with_defines")
load("//:bazel/oss_java_library.bzl", "oss_java_library")
load("//:bazel/sonatype_artifact_bundle.bzl", "sonatype_artifact_bundle")
load("//:bazel/typedast.bzl", "typedast")

package(licenses = ["notice"])

exports_files([
    "LICENSE",
])

filegroup(
    name = "sonatype_bundles",
    srcs = [
        ":compiler_externs_bundle",
        ":compiler_main_bundle",
        ":compiler_parent_bundle",
        ":compiler_shaded_bundle",
        ":compiler_unshaded_bundle",
    ],
)

sonatype_artifact_bundle(
    name = "compiler_shaded_bundle",
    artifact_id = "closure-compiler",
    jar = ":compiler_shaded.jar",
    javadoc = ":compiler_lib_no_runtime_libs.javadoc",
    pom = "maven/closure-compiler.pom.xml",
    sources = ":compiler_lib_no_runtime_libs.sources",
)

sonatype_artifact_bundle(
    name = "compiler_unshaded_bundle",
    artifact_id = "closure-compiler-unshaded",
    jar = ":compiler_unshaded",
    javadoc = ":compiler_lib_no_runtime_libs.javadoc",
    pom = ":compiler_unshaded-pom",
    sources = ":compiler_lib_no_runtime_libs.sources",
)

sonatype_artifact_bundle(
    name = "compiler_externs_bundle",
    artifact_id = "closure-compiler-externs",
    jar = ":externs",
    pom = "maven/closure-compiler-externs.pom.xml",
)

sonatype_artifact_bundle(
    name = "compiler_main_bundle",
    artifact_id = "closure-compiler-main",
    pom = "maven/closure-compiler-main.pom.xml",
)

sonatype_artifact_bundle(
    name = "compiler_parent_bundle",
    artifact_id = "closure-compiler-parent",
    pom = "maven/closure-compiler-parent.pom.xml",
)

jar_jar(
    name = "compiler_shaded",
    input_jar = ":compiler_uberjar_deploy.jar",
    rules = "rules.jarjar",
)

java_binary(
    name = "compiler_uberjar",
    main_class = "com.google.javascript.jscomp.CommandLineRunner",
    resources = [
        ":LICENSE",
    ],
    runtime_deps = [":compiler_lib"],
)

version = "$(COMPILER_VERSION)" or "1.0-SNAPSHOT"

genrule(
    name = "third_party_licenses_genrule",
    srcs = [
        "//license_check:THIRD_PARTY_NOTICES",
    ],
    outs = [
        "THIRD_PARTY_NOTICES",
    ],
    cmd = "cp $(location //license_check:THIRD_PARTY_NOTICES) $(location THIRD_PARTY_NOTICES)",
)

java_export(
    name = "compiler_unshaded",
    maven_coordinates = "com.google.javascript:closure-compiler-unshaded:{0}".format(version),
    pom_template = "maven/closure-compiler-unshaded.pom.xml.tpl",
    runtime_deps = [
        "//:compiler_unshaded_lib",
    ],
)

java_library(
    name = "compiler_unshaded_lib",
    srcs = [
        ":CommandLineRunnerVersion",
    ],
    resources = [
        ":LICENSE",
        ":THIRD_PARTY_NOTICES",
    ],
    deps = [
        "//:compiler_lib",
    ],
)

java_binary(
    name = "linter",
    main_class = "com.google.javascript.jscomp.LinterMain",
    runtime_deps = [":compiler_lib"],
)

java_binary(
    name = "instrumentationReporter",
    main_class = "com.google.javascript.jscomp.instrumentation.reporter.ProductionInstrumentationReporter",
    runtime_deps = [":compiler_lib"],
)

java_library(
    name = "externs",
    resources = [":externs_zip"],
)

java_library(
    name = "compiler_lib",
    resources = [
        ":src/java/com/google/javascript/jscomp/js/polyfills.txt",
        ":runtime_libs_srcs",
        ":runtime_libs_typedast",
    ],
    exports = [":compiler_lib_no_runtime_libs"],
)

typedast(
    name = "runtime_libs_typedast",
    srcs = [":runtime_libs_srcs"],
    compiler = ":compiler_unshaded_no_runtime_libs",
)

genrule(
    name = "gen_polyfill_table",
    srcs = [":runtime_libs_srcs"],
    outs = ["src/java/com/google/javascript/jscomp/js/polyfills.txt"],
    cmd = "node $(location src/com/google/javascript/jscomp/js/build_polyfill_table.js) $(SRCS) | sed 's,[^ ]*jscomp/js/,,g' > $@",
    tools = [
        "src/com/google/javascript/jscomp/js/build_polyfill_table.js",
    ],
)

filegroup(
    name = "runtime_libs_srcs",
    srcs = glob(
        ["src/com/google/javascript/jscomp/js/**/*.js"],
        exclude = [
            "src/com/google/javascript/jscomp/js/build_polyfill_table.js",
        ],
    ),
)

java_binary(
    name = "compiler_unshaded_no_runtime_libs",
    main_class = "com.google.javascript.jscomp.CommandLineRunner",
    resources = [
        ":LICENSE",
        ":THIRD_PARTY_NOTICES",
    ],
    runtime_deps = [":compiler_lib_no_runtime_libs"],
)

oss_java_library(
    name = "compiler_lib_no_runtime_libs",
    java_attrs = dict(
        javacopts = [
            "-source 11",
            "-target 11",
        ],
        resources = [
            ":LICENSE",
            ":THIRD_PARTY_NOTICES",
            ":externs_zip",
        ] + glob([
            "src/**/*.properties",
        ]),
    ),
    javadoc_attrs = dict(
    ),
    shared_attrs = dict(
        srcs = [
            ":CommandLineRunnerVersion",
        ] + glob(
            [
                "src/com/google/**/*.java",
            ],
            exclude = [
                "**/debugger/**/*.java",
                "**/j2clbuild/**/*.java",
                "**/j2cl/**/*.java",
                "**/super*/**/*.java",
                "**/testing/**/*.java",
                "**/webservice/**/*.java",
            ],
        ),
        deps = [
            "//src/com/google/debugging/sourcemap/proto:mapping_java_proto",
            "//src/com/google/javascript/jscomp/conformance:conformance_java_proto",
            "//src/com/google/javascript/jscomp/instrumentation/reporter/proto:profile_java_proto",
            "//src/com/google/javascript/rhino/typed_ast:typed_ast_java_proto",
            "@google_bazel_common//third_party/java/auto:value",
            "@maven//:args4j_args4j",
            "@maven//:com_google_code_gson_gson",
            "@maven//:com_google_errorprone_error_prone_annotations",
            "@maven//:com_google_guava_failureaccess",
            "@maven//:com_google_guava_guava",
            "@maven//:com_google_protobuf_protobuf_java",
            "@maven//:com_google_re2j_re2j",
            "@maven//:org_apache_ant_ant",
            "@maven//:org_jspecify_jspecify",
        ],
    ),
)

genrule(
    name = "externs_zip",
    srcs = glob(["externs/**/*.js"]),
    outs = ["externs.zip"],
    # Trim the "externs/" prefix from the names of the ziped files.
    cmd = "cd externs && find . -name '*.js' | zip ../$(OUTS) -@ &> /dev/null",
)

# It's easier to make a copy of this Java file because the Java compiler can
# tell us during build if something is wrong. By contrast, a resource lookup
# will fail at runtime.
expand_template_with_defines(
    name = "CommandLineRunnerVersion",
    out = "CommandLineRunnerVersion.java",
    defines = {
        "COMPILER_VERSION": "unspecified",
    },
    substitutions = {
        "inlineDefine_COMPILER_VERSION": "{COMPILER_VERSION}",
    },
    template = "src/com/google/javascript/jscomp/CommandLineRunnerVersion.template",
)

# To run all tests:           `blaze test //:compiler_tests`
# To test `a/b/FooTest.java`: `blaze test //:a/b/Foo`
#
# Only files ending in `*Test.java` are considered tests.
gen_java_tests(
    name = "compiler_tests",
    srcs = glob(
        [
            "test/**/*.java",
            "src/**/testing/**/*.java",
        ],
        exclude = [
            # These files are only needed by the J2CL build of the compiler.
            "**/super*/**/*.java",
            "**/j2cl/**/*.java",
            "**/j2clbuild/**/*.java",
        ],
    ),
    javacopts = [
        "-source 11",
        "-target 11",
    ],
    prefix_path = "test/",
    deps = [
        ":compiler_lib",
        ":compiler_tests_resources",
        "//src/com/google/debugging/sourcemap/proto:mapping_java_proto",
        "//src/com/google/javascript/jscomp/conformance:conformance_java_proto",
        "//src/com/google/javascript/jscomp/instrumentation/reporter/proto:profile_java_proto",
        "//src/com/google/javascript/rhino/typed_ast:typed_ast_java_proto",
        "@google_bazel_common//third_party/java/auto:value",
        "@google_bazel_common//third_party/java/junit",
        "@google_bazel_common//third_party/java/mockito",
        "@google_bazel_common//third_party/java/truth",
        "@maven//:args4j_args4j",
        "@maven//:com_google_code_gson_gson",
        "@maven//:com_google_errorprone_error_prone_annotations",
        "@maven//:com_google_guava_failureaccess",
        "@maven//:com_google_guava_guava",
        "@maven//:com_google_guava_guava_testlib",
        "@maven//:com_google_jimfs_jimfs",
        "@maven//:com_google_protobuf_protobuf_java",
        "@maven//:com_google_re2j_re2j",
        "@maven//:com_google_truth_extensions_truth_liteproto_extension",
        "@maven//:com_google_truth_extensions_truth_proto_extension",
        "@maven//:io_github_java_diff_utils_java_diff_utils",
        "@maven//:org_jspecify_jspecify",
    ],
)

java_library(
    name = "compiler_tests_resources",
    # These files are read from runfiles.
    data = [
        "contrib/externs/chai-3.5.js",
    ] + glob([
        "test/com/google/javascript/jscomp/testdata/**/*",
        "test/com/google/javascript/jscomp/instrumentation/reporter/testdata/**/*",
        "test/com/google/javascript/refactoring/examples/**/testdata/**/*",
    ]),
    resources = glob([
        "src/com/google/javascript/refactoring/examples/refasterjs/**/*.js",
    ]),
)
